import 'package:fixnum/fixnum.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';

import '../../../../core/protos/v1/chat.pb.dart' as chat_proto;
import '../../../../utils/logger_util.dart';
import '../../../data/chat/convert_user_id.dart';
import '../../../services/websocket_service_protobuf.dart';

class CreateGroupController extends GetxController {
  var urlEditController = TextEditingController();

  var userNameEditController = TextEditingController();

  var groupNameEditController = TextEditingController();
  var groupDescEditController = TextEditingController();
  var groupOwnerEditController = TextEditingController();
  var groupUsersEditController = TextEditingController();

  static const defaultUrl = 'ws://192.168.1.183:8090/ws';
  static const token = '';

  final messageList = <chat_proto.ChatMessage>[].obs;

  @override
  void onInit() {
    super.onInit();

    Get.put(WebSocketServiceProtobuf());
  }

  @override
  void onReady() {
    super.onReady();

    updateUrlInputText(defaultUrl);
  }

  @override
  void onClose() {
    _disconnectWebsocket();
    super.onClose();
  }

  void updateUrlInputText(String text) {
    _updateUrlInputText(urlEditController, text);
  }

  void cleanUrlInputText() {
    _cleanInputText(urlEditController);
  }

  void updateUserNameInputText(String text) {
    _updateUrlInputText(userNameEditController, text);
  }

  void cleanUserNameInputText() {
    _cleanInputText(userNameEditController);
  }

  void updateGroupNameInputText(String text) {
    _updateUrlInputText(groupNameEditController, text);
  }

  void cleanGroupNameInputText() {
    _cleanInputText(groupNameEditController);
  }

  void updateGroupDescInputText(String text) {
    _updateUrlInputText(groupDescEditController, text);
  }

  void cleanGroupDescInputText() {
    _cleanInputText(groupDescEditController);
  }

  void updateGroupOwnerInputText(String text) {
    _updateUrlInputText(groupOwnerEditController, text);
  }

  void cleanGroupOwnerInputText() {
    _cleanInputText(groupOwnerEditController);
  }

  void updateGroupUsersInputText(String text) {
    _updateUrlInputText(groupUsersEditController, text);
  }

  void cleanGroupUsersInputText() {
    _cleanInputText(groupUsersEditController);
  }

  void _cleanInputText(TextEditingController editingController) {
    editingController.clear();
  }

  void _updateUrlInputText(
    TextEditingController editingController,
    String text,
  ) {
    editingController.text = text;
  }

  void connectWebsocket() {
    _connectWebsocket();
  }

  void _connectWebsocket() async {
    final startConnectMessage =
        chat_proto.ChatMessage()
          ..type = chat_proto.MessageType.UNKNOWN
          ..token = ''
          ..sender = Int64.parseInt('-1')
          ..receiver = Int64.parseInt('-1')
          ..groupId = Int64.parseInt('-1')
          ..content = '开始连接,请稍等...';

    _addMessage(startConnectMessage);

    final url =
        urlEditController.text.isEmpty ? defaultUrl : urlEditController.text;
    logE('_connectWebsocket url:$url');

    await WebSocketServiceProtobuf.to.connect(url, token);

    if (WebSocketServiceProtobuf.to.isConnected.value) {
      final connectMessage =
          chat_proto.ChatMessage()
            ..type = chat_proto.MessageType.UNKNOWN
            ..token = ''
            ..sender = Int64.parseInt('-1')
            ..receiver = Int64.parseInt('-1')
            ..groupId = Int64.parseInt('-1')
            ..content = '已连接';

      _addMessage(connectMessage);
    }

    _setupWebSocket();
  }

  void disconnectWebsocket() {
    _disconnectWebsocket();
  }

  void _disconnectWebsocket() {
    WebSocketServiceProtobuf.to.disconnect();

    final message =
        chat_proto.ChatMessage()
          ..type = chat_proto.MessageType.UNKNOWN
          ..token = ''
          ..sender = Int64.parseInt('-1')
          ..receiver = Int64.parseInt('-1')
          ..groupId = Int64.parseInt('-1')
          ..content = '已断开连接';
    _addMessage(message);
  }

  void _setupWebSocket() {
    WebSocketServiceProtobuf.to.stream.listen(
      (data) {
        logE('_setupWebSocket()-->data:$data');

        chat_proto.MessageWrapper messageWrapper = chat_proto
            .MessageWrapper.fromBuffer(data);
        logE('_setupWebSocket()-->messageWrapper:$messageWrapper');

        _handlerMessage(messageWrapper);
      },
      onDone: () => _disconnectWebsocket(),
      onError: (err) {
        logE('_setupWebSocket()-->onError:$err');

        _disconnectWebsocket();
      },
    );
  }

  void _handlerMessage(chat_proto.MessageWrapper messageWrapper) {
    switch (messageWrapper.type) {
      case chat_proto.MessageType.REGISTER:
        final chat_proto.Response registerResponse = chat_proto
            .Response.fromBuffer(messageWrapper.payload);

        logE('_handlerMessage()-->registerResponse:$registerResponse');

        String msg =
            registerResponse.success
                ? '注册成功'
                : '注册失败！${registerResponse.message}';

        final registerMessage =
            chat_proto.ChatMessage()
              ..type = chat_proto.MessageType.UNKNOWN
              ..token = ''
              ..sender = Int64.parseInt('-1')
              ..receiver = Int64.parseInt('-1')
              ..groupId = Int64.parseInt('-1')
              ..content = msg;

        _addMessage(registerMessage);
        break;
      case chat_proto.MessageType.LOGIN:
        final chat_proto.Response loginResponse = chat_proto
            .Response.fromBuffer(messageWrapper.payload);

        logE('_handlerMessage()-->loginResponse:$loginResponse');

        String msg =
            loginResponse.success ? '登录成功' : '登录失败！${loginResponse.message}';

        final loginMessage =
            chat_proto.ChatMessage()
              ..type = chat_proto.MessageType.UNKNOWN
              ..token = ''
              ..sender = Int64.parseInt('-1')
              ..receiver = Int64.parseInt('-1')
              ..groupId = Int64.parseInt('-1')
              ..content = msg;

        _addMessage(loginMessage);
        break;
      case chat_proto.MessageType.LOGOUT:
        break;
      case chat_proto.MessageType.PRIVATE_CHAT:
        break;
      case chat_proto.MessageType.GROUP_CHAT:
        break;
      case chat_proto.MessageType.CREATE_GROUP:
        // final chat_proto.CreateGroupResponse createGroupResponse = chat_proto
        //     .CreateGroupResponse.fromBuffer(messageWrapper.payload);

        final chat_proto.Response createGroupResponse = chat_proto
            .Response.fromBuffer(messageWrapper.payload);

        logE('_handlerMessage()-->createGroupResponse:$createGroupResponse');

        // String msg =
        //     '创建成功。群Id:${createGroupResponse.groupId}，群名称:${createGroupResponse.groupName}，群描述:${createGroupResponse.groupDesc}，群主:${createGroupResponse.groupOwner}，群成员:${createGroupResponse.groupUsers}';

        String msg =
            createGroupResponse.success
                ? '创建成功。群Id:${createGroupResponse.message}'
                : '创建失败！';

        final createGroupMessage =
            chat_proto.ChatMessage()
              ..type = chat_proto.MessageType.UNKNOWN
              ..token = ''
              ..sender = Int64.parseInt('-1')
              ..receiver = Int64.parseInt('-1')
              ..groupId = Int64.parseInt('-1')
              ..content = msg;

        _addMessage(createGroupMessage);
        break;
      case chat_proto.MessageType.INVITE_GROUP:
        break;
      default:
        break;
    }
  }

  void _addMessage(chat_proto.ChatMessage message) {
    messageList.insert(0, message);
  }

  void login() {
    if (userNameEditController.text.isEmpty) {
      Get.snackbar('温馨提示', '请输入用户名');
      return;
    }

    final userId = userNameEditController.text;

    final loginRequest = chat_proto.LoginRequest(
      username: userId,
      password: '',
      token: '',
      deviceId: '',
    );

    logE('_login()->loginRequest:${loginRequest.writeToBuffer()}');

    final loginWrapper = chat_proto.MessageWrapper(
      type: chat_proto.MessageType.LOGIN,
      payload: loginRequest.writeToBuffer(),
    );

    final send = loginWrapper.writeToBuffer();
    logE('_login()->message:$send');

    WebSocketServiceProtobuf.to.sendMessage(send);

    final loginMessage =
        chat_proto.ChatMessage()
          ..type = chat_proto.MessageType.UNKNOWN
          ..token = ''
          ..sender = Int64.parseInt('-1')
          ..receiver = Int64.parseInt('-1')
          ..groupId = Int64.parseInt('-1')
          ..content = '正在登录，请稍等...';

    _addMessage(loginMessage);
  }

  void createGroup() {
    final groupName = groupNameEditController.text.trim();
    final groupDesc = groupDescEditController.text.trim();
    final groupOwner = userNameEditController.text.trim();
    final groupUsers = groupUsersEditController.text.trim();

    if (groupName.isEmpty) {
      Get.snackbar('温馨提示', '请输入群名称');
      return;
    }
    if (groupDesc.isEmpty) {
      Get.snackbar('温馨提示', '请输入群描述');
      return;
    }

    if (groupOwner.isEmpty) {
      Get.snackbar('温馨提示', '请输入用户名');
      return;
    }

    if (groupUsers.isEmpty) {
      Get.snackbar('温馨提示', '请输入群用户');
      return;
    }

    final groupOwnerInt = Int64.parseInt(convertUserIdByUserName(groupOwner));
    final userList = parseGroupUserList(groupUsers);

    final chat_proto.CreateGroupRequest createGroupRequest =
        chat_proto.CreateGroupRequest(
          groupName: groupName,
          groupDesc: groupDesc,
          groupOwner: groupOwnerInt,
          groupUsers: userList,
        );
    logE('createGroup()-->createGroupRequest：$createGroupRequest');

    final chat_proto.MessageWrapper createGroupWrapper =
        chat_proto.MessageWrapper(
          type: chat_proto.MessageType.CREATE_GROUP,
          payload: createGroupRequest.writeToBuffer(),
        );

    logE('createGroup()-->createGroupWrapper：$createGroupWrapper');

    WebSocketServiceProtobuf.to.sendMessage(createGroupWrapper.writeToBuffer());

    final createGroupMessage =
        chat_proto.ChatMessage()
          ..type = chat_proto.MessageType.UNKNOWN
          ..token = ''
          ..sender = Int64.parseInt('-1')
          ..receiver = Int64.parseInt('-1')
          ..groupId = Int64.parseInt('-1')
          ..content = '正在创建群，请稍等...';

    _addMessage(createGroupMessage);
  }

  List<Int64> parseGroupUserList(String users) {
    List<Int64> userList = [];

    List<String> list = users.split(',');

    for (var value in list) {
      final user = Int64.parseInt(convertUserIdByUserName(value));
      userList.add(user);
    }

    return userList;
  }
}
